# -*- coding:utf-8 -*-
"""
@project: API_Automation
@author: chenhh
@file: SetupTeardown.py
@ide: PyCharm
@time: 2021/2/24
"""

from Casedata.Casedata import Casedata
from Common import Consts, Log, Assert, Request, Extract_data
import json
from Casedata import Casedata
from Common.Mysql_operate import MysqlDb


class Setupteardownmethod(object):

	log = Log.MyLog()
	test = Assert.Assertions()
	request = Request.RequestInterface()
	extract = Extract_data.Extractdata()
	db = MysqlDb()

	def __init__(self, filename):
		data = Casedata.Casedata(filename)
		self.case_list = data.get_caselist()[0]
		self.n = data.get_caselist()[1]

	'''
	封装前置操作:以英文分号分隔，提取前置内容
		1、内容为SQL，则执行SQL；
		2、字符串如果以case_开头，则执行用例
		3、字符串如果是变量名，则引用全局变量
	'''
	def setup_public(self, setup_data, param):
		try:
			setup_list = setup_data.split(';')
			param = param
			for i in range(0, len(setup_list)):
				try:
					# print("进入setup_list循环", len(setup_list), i)
					setup_data = setup_list[i]
					if setup_data != '':
						# 1.内容为SQL，则执行SQL；
						if isinstance(setup_data, str) and setup_data.lower().startswith('delete'):
							self.db.execute_db(setup_data)
						# print('delete成功')
						elif isinstance(setup_data, str) and setup_data.lower().startswith('update'):
							self.db.execute_db(setup_data)
						# print('update成功')
						# 2、字符串如果以case_开头，则执行用例
						elif setup_data.lower().startswith('case_'):
							try:
								for j in range(0, self.n):
									num = self.case_list[j][0]
									# print('params', self.case_list)
									# print('循环比较num', j, num)
									if num != setup_data:
										#print("num不等于i,退出本次循环")
										continue
									title = self.case_list[j][1]
									url = self.case_list[j][2]
									restype = self.case_list[j][3]
									par = self.case_list[j][4]
									setup_data = self.case_list[j][5]
									teardown_data = self.case_list[j][6]
									self.demo_api(num, title, url, restype, par, setup_data, teardown_data)
								# print('前置执行用例执行成功,%s'% num)
							except:
								continue
						# 3、字符串如果是变量名，则引用全局变量
						else:
							setup_data = Consts.API_EXTRACTPARAM[setup_data]
							param = param.format(setup_data)
						# print(param)
				except:
					raise
			return param
		except:
			self.log.info("前置操作失败,setup=%s " % setup_data)
			raise

	'''
	封装后置操作
	提取参数；格式：参数名 = 提取路径(以.分割)
	'''
	def teardown_public(self, response, param):
		# 提取参数；格式：参数名 = 提取路径(以.分割)
		pa = param.split('=')
		name = pa[0]  # 参数名
		param = pa[1]  # 提取路径(以.分割)
		try:
			# 写入全局变量Consts.API_EXTRACTPARAM
			opr = self.extract.public_extract(response, param)
			a = {name: opr}
			Consts.API_EXTRACTPARAM.update(a)
		except:
			self.log.info("后置操作失败，response={}，提取参数={}".format(response, param))

	'''
	用例执行
	'''

	def demo_api(self, num, title, url, restype, param, setup_data, teardown_data):
		try:

			# 判断是否需要前置操作
			if setup_data != '':
				param = self.setup_public(setup_data, param)

			# 接口请求
				response = self.request.http_request(interface_url=url, interface_param=param, request_type=restype)
				data = json.loads(response)
				# 断言结果
				assert self.test.assert_body(data, "result", True)
				# 判断是否需要后置操作
				if teardown_data != '':
					self.teardown_public(data, teardown_data)
					self.log.info("用例执行成功 ：%s%s " % (num, title))

		except:
			self.log.info("用例执行失败 ：%s%s " % (num, title))
			raise
